package com.luban;

import com.luban.mapper.OrderMapper;
import com.luban.mapper.UserMapper;
import com.luban.service.UserService;
import com.luban.springmybatisluban.*;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;

import java.io.IOException;
import java.io.InputStream;

@ComponentScan("com.luban")
@Import(MapperImportBeanDefinitionRegistrar.class)//MapperImportBeanDefinitionRegistrar进行BeanDefinition的注册
public class LubanApplication {

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
        return new SqlSessionFactoryBuilder().build(inputStream);
    }

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(LubanApplication.class);
        applicationContext.refresh();

        //UserService
        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.test();
    }

    public static void testFactoryBean03() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(LubanApplication.class);

        //定义并注册一个beanDefinition
        AbstractBeanDefinition beanDefinition0 = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition0.setBeanClass(MapperFactoryBean.class); //MapperFactoryBean +  getObject()-UserMapper的代理对象
        beanDefinition0.getConstructorArgumentValues().addGenericArgumentValue(UserMapper.class);
        applicationContext.registerBeanDefinition("userMapper", beanDefinition0);


        //定义并注册一个beanDefinition
        AbstractBeanDefinition beanDefinition1 = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition1.setBeanClass(MapperFactoryBean.class); //MapperFactoryBean +  getObject()-OrderMapper的代理对象
        beanDefinition1.getConstructorArgumentValues().addGenericArgumentValue(OrderMapper.class);
        applicationContext.registerBeanDefinition("orderMapper", beanDefinition1);


        applicationContext.refresh();


        //UserService
        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.test();

    }

    /**
     * MapperFactoryBean +  getObject()-UserMapper的代理对象
     * MapperFactoryBean +  getObject()-OrderMapper的代理对象
     */
    public static void testFactoryBean02() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(LubanApplication.class);

        //定义并注册一个beanDefinition
        AbstractBeanDefinition beanDefinition0 = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition0.setBeanClass(MapperFactoryBean.class); //MapperFactoryBean +  getObject()-UserMapper的代理对象
        beanDefinition0.getConstructorArgumentValues().addGenericArgumentValue(UserMapper.class);
        applicationContext.registerBeanDefinition("userMapper", beanDefinition0);


        //定义并注册一个beanDefinition
        AbstractBeanDefinition beanDefinition1 = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition1.setBeanClass(MapperFactoryBean.class); //MapperFactoryBean +  getObject()-OrderMapper的代理对象
        beanDefinition1.getConstructorArgumentValues().addGenericArgumentValue(OrderMapper.class);
        applicationContext.registerBeanDefinition("orderMapper", beanDefinition1);


        applicationContext.refresh();


        //UserService
        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.test();
    }


    /**
     * UserMapperFactoryBean +  getObject()
     * OrderMapperFactoryBean +  getObject()
     */
    public static void testFactoryBean01() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(LubanApplication.class);

        //定义并注册一个beanDefinition
        AbstractBeanDefinition beanDefinition0 = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition0.setBeanClass(UserMapperFactoryBean.class); //UserMapperFactoryBean +  getObject()
        applicationContext.registerBeanDefinition("userMapper", beanDefinition0);

        //定义并注册一个beanDefinition
        AbstractBeanDefinition beanDefinition1 = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition1.setBeanClass(OrderMapperFactoryBean.class); //OrderMapperFactoryBean +  getObject()
        applicationContext.registerBeanDefinition("orderMapper", beanDefinition1);

        applicationContext.refresh();


        //UserService
        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.test();
    }

    /**
     * testFactoryBean
     */
    public static void testFactoryBean00() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(LubanApplication.class);

        //定义并注册一个beanDefinition
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition.setBeanClass(UserFactoryBean.class); //LubanFactoryBean + getObject()
        applicationContext.registerBeanDefinition("user", beanDefinition);


        applicationContext.refresh();


        System.out.println(applicationContext.getBean("user")); //com.luban.service.User@3c0a50da
        System.out.println(applicationContext.getBean("&user")); //org.mybatis.spring.LubanFactoryBean@646be2c3
    }
}
